#include "lcdtouchpad.h"

uint16_t lcd_touchpad_touch_regtable[10]=
{
    LCD_TOUCHPAD_TP1_REG,LCD_TOUCHPAD_TP2_REG,
    LCD_TOUCHPAD_TP3_REG,LCD_TOUCHPAD_TP4_REG,
    LCD_TOUCHPAD_TP5_REG,LCD_TOUCHPAD_TP6_REG,
    LCD_TOUCHPAD_TP7_REG,LCD_TOUCHPAD_TP8_REG,
    LCD_TOUCHPAD_TP9_REG,LCD_TOUCHPAD_TP10_REG
};
lcd_touchpad_pos_t lcd_touchpad_pos[10]={0};
void lcd_touchpad_init(void)
{
//     lcd_init();
//     delay_ms(500);
//     __HAL_RCC_GPIOC_CLK_ENABLE();
//     __HAL_RCC_GPIOB_CLK_ENABLE();
//     GPIO_InitTypeDef gpio_initstruct={0};
    
//     gpio_initstruct.Mode=GPIO_MODE_OUTPUT_PP;
//     gpio_initstruct.Pull=GPIO_PULLUP;
//     gpio_initstruct.Pin=LCD_TOUCHPAD_RESET_PIN;
//     gpio_initstruct.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
//     HAL_GPIO_Init(LCD_TOUCHPAD_RESET_PORT,&gpio_initstruct);
//     //HAL_GPIO_WritePin(LCD_TOUCHPAD_RESET_PORT,LCD_TOUCHPAD_RESET_PIN,GPIO_PIN_RESET);

//     gpio_initstruct.Mode=GPIO_MODE_INPUT;
//     gpio_initstruct.Pull=GPIO_PULLUP;
//     gpio_initstruct.Pin=LCD_TOUCHPAD_INT_PIN;
//     gpio_initstruct.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
//     HAL_GPIO_Init(LCD_TOUCHPAD_INT_PORT,&gpio_initstruct);
//     //HAL_GPIO_WritePin(LCD_TOUCHPAD_INT_PORT,LCD_TOUCHPAD_INT_PIN,GPIO_PIN_SET);
//     //delay_ms(200);
//     //HAL_GPIO_WritePin(LCD_TOUCHPAD_RESET_PORT,LCD_TOUCHPAD_RESET_PIN,GPIO_PIN_SET);
//     // delay_ms(10);

//     lcd_touchpad_i2c_init();
//     HAL_GPIO_WritePin(LCD_TOUCHPAD_RESET_PORT,LCD_TOUCHPAD_RESET_PIN,GPIO_PIN_RESET);
//     delay_ms(10);
//     HAL_GPIO_WritePin(LCD_TOUCHPAD_RESET_PORT,LCD_TOUCHPAD_RESET_PIN,GPIO_PIN_SET);
//     delay_ms(10);
//     gpio_initstruct.Mode=GPIO_MODE_INPUT;
//     gpio_initstruct.Pull=GPIO_NOPULL;
//     gpio_initstruct.Pin=LCD_TOUCHPAD_INT_PIN;
//     gpio_initstruct.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
//     HAL_GPIO_Init(LCD_TOUCHPAD_INT_PORT,&gpio_initstruct);
//     delay_ms(100);

//     uint8_t temp[5]={0};

// //    temp[0]=0x02;
// //    lcd_touchpad_wr_reg(GT9147_COMMAND_REG,temp,1);
// //    delay_ms(100);

//     lcd_touchpad_rd_reg(GT9147_PRODUCT_ID_REG,temp,4);
//     printf("GT9147_PRODUCT_ID_REG: %s\n",temp);
    lcd_init();
    lcd_touchpad_i2c_init();
    //delay_ms(500);
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    GPIO_InitTypeDef gpio_initstruct={0};
    
    gpio_initstruct.Mode=GPIO_MODE_OUTPUT_PP;
    gpio_initstruct.Pull=GPIO_PULLUP;
    gpio_initstruct.Pin=LCD_TOUCHPAD_RESET_PIN;
    gpio_initstruct.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(LCD_TOUCHPAD_RESET_PORT,&gpio_initstruct);
    HAL_GPIO_WritePin(LCD_TOUCHPAD_RESET_PORT,LCD_TOUCHPAD_RESET_PIN,GPIO_PIN_RESET);

    gpio_initstruct.Mode=GPIO_MODE_OUTPUT_PP;
    gpio_initstruct.Pull=GPIO_PULLUP;
    gpio_initstruct.Pin=LCD_TOUCHPAD_INT_PIN;
    gpio_initstruct.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(LCD_TOUCHPAD_INT_PORT,&gpio_initstruct);
    HAL_GPIO_WritePin(LCD_TOUCHPAD_INT_PORT,LCD_TOUCHPAD_INT_PIN,GPIO_PIN_SET);
    delay_us(150);
    HAL_GPIO_WritePin(LCD_TOUCHPAD_RESET_PORT,LCD_TOUCHPAD_RESET_PIN,GPIO_PIN_SET);
    delay_ms(6);
		HAL_GPIO_WritePin(LCD_TOUCHPAD_INT_PORT,LCD_TOUCHPAD_INT_PIN,GPIO_PIN_RESET);
    delay_us(60);
		
    gpio_initstruct.Mode=GPIO_MODE_INPUT;
    gpio_initstruct.Pull=GPIO_NOPULL;
    gpio_initstruct.Pin=LCD_TOUCHPAD_INT_PIN;
    gpio_initstruct.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(LCD_TOUCHPAD_INT_PORT,&gpio_initstruct);

    uint8_t temp[5]={0};

    temp[0]=0x02;
    lcd_touchpad_wr_reg(LCD_TOUCHPAD_COMMAND_REG,temp,1);
    delay_ms(100);

    lcd_touchpad_rd_reg(LCD_TOUCHPAD_PRODUCT_ID_REG,temp,4);
    // printf_("GT9147_PRODUCT_ID_REG: %s\n",temp);
}

uint8_t lcd_touchpad_wr_reg(uint16_t reg, uint8_t *data,uint16_t len)
{
    lcd_touchpad_i2c_start();
    lcd_touchpad_i2c_send_byte(LCD_TOUCHPAD_I2C_ADDR);
    if(!lcd_touchpad_i2c_wait_ack())    return 0;
    lcd_touchpad_i2c_send_byte((uint8_t)(reg>>8));
    if(!lcd_touchpad_i2c_wait_ack())    return 0;
    lcd_touchpad_i2c_send_byte((uint8_t)reg);
    if(!lcd_touchpad_i2c_wait_ack())    return 0;
    for (uint16_t i = 0; i < len; i++)
    {
        lcd_touchpad_i2c_send_byte(data[i]);
        if(!lcd_touchpad_i2c_wait_ack())    return 0;
    }
    lcd_touchpad_i2c_stop();
    return 1;
}

uint8_t lcd_touchpad_rd_reg(uint16_t reg,uint8_t *data,uint16_t len)
{
    lcd_touchpad_i2c_start();
    lcd_touchpad_i2c_send_byte(LCD_TOUCHPAD_I2C_ADDR);
    if(!lcd_touchpad_i2c_wait_ack())    return 0;
    lcd_touchpad_i2c_send_byte((uint8_t)(reg>>8));
    if(!lcd_touchpad_i2c_wait_ack())    return 0;
    lcd_touchpad_i2c_send_byte((uint8_t)reg);
    if(!lcd_touchpad_i2c_wait_ack())    return 0;
    lcd_touchpad_i2c_stop();
    lcd_touchpad_i2c_start();
    lcd_touchpad_i2c_send_byte(LCD_TOUCHPAD_I2C_ADDR|0x01);
    if(!lcd_touchpad_i2c_wait_ack())    return 0;
    for (uint16_t i = 0; i < len; i++)
    {
        data[i]=lcd_touchpad_i2c_read_byte(i != len-1);
    }
    lcd_touchpad_i2c_stop();
    return 1;
}


uint8_t lcd_touchpad_scan(void)
{
    static uint8_t state=0,touch_num=0;
    lcd_touchpad_rd_reg(LCD_TOUCHPAD_STATUS_REG,&state,1);
    uint8_t tmp_touchpos[4]={0};
    if(state&0x80)
    {
        touch_num=state&0x0F;
        for (uint8_t i = 0; i < touch_num; i++)
        {
            lcd_touchpad_rd_reg(lcd_touchpad_touch_regtable[i],tmp_touchpos,4);
            lcd_touchpad_pos[i].x=tmp_touchpos[0]|(((uint16_t)(tmp_touchpos[1]))<<8);
            lcd_touchpad_pos[i].y=tmp_touchpos[2]|(((uint16_t)(tmp_touchpos[3]))<<8);
        }
        state=0;
        lcd_touchpad_wr_reg(LCD_TOUCHPAD_STATUS_REG,&state,1);
				return touch_num;
    }

	return 0;
}

void lcd_touchpad_get_pos(int16_t *x,int16_t *y)
{
    static uint8_t state=0,touch_num=0;
    lcd_touchpad_rd_reg(LCD_TOUCHPAD_STATUS_REG,&state,1);
    uint8_t tmp_touchpos[4]={0};
    touch_num=state&0x0F;
    for (uint8_t i = 0; i < touch_num; i++)
    {
        lcd_touchpad_rd_reg(lcd_touchpad_touch_regtable[i],tmp_touchpos,4);
        if (lcddev.dir==0)
        {
            *x=(tmp_touchpos[0]|(((uint16_t)(tmp_touchpos[1]))<<8));
            *y=(tmp_touchpos[2]|(((uint16_t)(tmp_touchpos[3]))<<8));
        }
        else
        {
            *y=(tmp_touchpos[0]|(((uint16_t)(tmp_touchpos[1]))<<8));
            *x=abs((tmp_touchpos[2]|(((uint16_t)(tmp_touchpos[3]))<<8))-800);
        }
    }
    state=0;
    lcd_touchpad_wr_reg(LCD_TOUCHPAD_STATUS_REG,&state,1);
}

void lcd_touchpad_i2c_init(void)
{
    LCD_TOUCHPAD_I2C_SCL_ENABLE();
    LCD_TOUCHPAD_I2C_SDA_ENABLE();
    GPIO_InitTypeDef gpio_initstruct={0};
    gpio_initstruct.Mode=GPIO_MODE_OUTPUT_PP;
    gpio_initstruct.Pull=GPIO_PULLUP;
    gpio_initstruct.Pin=LCD_TOUCHPAD_I2C_SCL_PIN;
    gpio_initstruct.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(LCD_TOUCHPAD_I2C_SCL_PORT,&gpio_initstruct);

    gpio_initstruct.Mode=GPIO_MODE_OUTPUT_OD;
    gpio_initstruct.Pull=GPIO_PULLUP;
    gpio_initstruct.Pin=LCD_TOUCHPAD_I2C_SDA_PIN;
    gpio_initstruct.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(LCD_TOUCHPAD_I2C_SDA_PORT,&gpio_initstruct);
    // LCD_TOUCHPAD_I2C_SCL(0);
    // LCD_TOUCHPAD_I2C_SDA(1);
    lcd_touchpad_i2c_stop();
}

uint8_t lcd_touchpad_touched(void)
{
    static uint8_t statereg;
    lcd_touchpad_rd_reg(LCD_TOUCHPAD_STATUS_REG,&statereg,1);
    return statereg&0x80;

}

void lcd_touchpad_i2c_start(void)
{
    LCD_TOUCHPAD_I2C_SDA(1);
    LCD_TOUCHPAD_I2C_SCL(1);
    LCD_TOUCHPAD_I2C_SDA(0);
    LCD_TOUCHPAD_I2C_SCL(0);
}

void lcd_touchpad_i2c_stop(void)
{
    LCD_TOUCHPAD_I2C_SCL(0);
    LCD_TOUCHPAD_I2C_SDA(0);
    LCD_TOUCHPAD_I2C_SCL(1);
    LCD_TOUCHPAD_I2C_SDA(1);
}

uint8_t lcd_touchpad_i2c_wait_ack(void)
{
    LCD_TOUCHPAD_I2C_SDA(1);
    LCD_TOUCHPAD_I2C_SCL(1);
    uint32_t retry=10000;
    while (LCD_TOUCHPAD_IIC_READ_SDA)
    {
        if(!(retry--)) 
        {
            lcd_touchpad_i2c_stop();
            return 0;
        }       
    }
    LCD_TOUCHPAD_I2C_SCL(0);
    return 1;
}

void lcd_touchpad_i2c_ack(void)
{
    LCD_TOUCHPAD_I2C_SDA(0);
    LCD_TOUCHPAD_I2C_SCL(1);
    LCD_TOUCHPAD_I2C_SCL(0);
    LCD_TOUCHPAD_I2C_SDA(1);
}
void lcd_touchpad_i2c_nack(void)
{
    LCD_TOUCHPAD_I2C_SDA(1);
    LCD_TOUCHPAD_I2C_SCL(1);
    LCD_TOUCHPAD_I2C_SCL(0);
}
void lcd_touchpad_i2c_send_byte(uint8_t data)
{
    for(uint8_t i = 0;i<8;i++)
    {     
        LCD_TOUCHPAD_I2C_SDA(((data<<i)&0x80)>>7);
        LCD_TOUCHPAD_I2C_SCL(1);
        LCD_TOUCHPAD_I2C_SCL(0);
    }
    LCD_TOUCHPAD_I2C_SDA(1);
}

uint8_t lcd_touchpad_i2c_read_byte(unsigned char ack)/* IIC读取一个字节 */
{
    uint8_t data=0;
    for(uint8_t i = 0;i<8;i++)
    {
        data<<=1;
        LCD_TOUCHPAD_I2C_SCL(1);
        if(LCD_TOUCHPAD_IIC_READ_SDA) data++;
        LCD_TOUCHPAD_I2C_SCL(0);
    }
    if(ack)
        lcd_touchpad_i2c_ack();
    else
        lcd_touchpad_i2c_nack();
    return data;
}

